/**
 * ReportGear(2011)
 */
package com.reportgear.report.model.calculator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.abbp.core.util.NumberUtils;
import net.abbp.report.model.Cell;
import net.abbp.report.model.ReportModel;
import net.abbp.report.view.cell.value.ImageValue;
import net.abbp.report.view.cell.value.JsDataValue;

import com.reportgear.core.data.SalaryHelper;
import com.reportgear.core.data.model.SalaryDataObject;

/**
 * 
 * 简历计算器
 * 
 * @version 1.0 2011-4-10
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public class ResumeCalculator extends AbstractCalculator {
    // 公式字段正则表达式
    private static final Pattern REG_FIELD = Pattern.compile("\\{(.*?)\\}");
    // 数据缓存
    private Map<String, Object> dataCache = new HashMap<String, Object>();

    /**
     * 通过dataSourceId获取数据(没有考虑并发)
     * 
     * @param dataSourceId
     *            数据源Id
     * @param parameter
     * @return 数据
     */
    private Object getData(String dataSourceId, CalcParameter parameter) {
        Object data = dataCache.get(dataSourceId);

        if (data == null) {
            SalaryHelper helper = SalaryHelper.INSTANCE;
            int personId = NumberUtils.convertToInteger(parameter.getParameter("PersonId"), 0);

            if ("员工履历".equals(dataSourceId)) {
                data = helper.getResumeBase(personId);
            } else {
                data = helper.getResumeParts(personId, dataSourceId);
            }

            this.dataCache.put(dataSourceId, data);
        }

        return data;
    }

    public ResumeCalculator() {

    }

    @Override
    public ReportModel calculate(ReportModel model, CalcParameter parameter) {
        if (logger.isDebugEnabled()) {
            logger.debug("计算模型：简历");
        }

        ReportModel calcModel = model;

        Iterator<Cell> cells = calcModel.getCellsIteratorByCellElementClass(JsDataValue.class);
        for (Iterator<Cell> i = cells; i.hasNext();) {
            Cell cell = i.next();

            JsDataValue jdfo = (JsDataValue) cell.getValue();
            // 数据源
            String dataSourceCaption = jdfo.getDataSourceCaption();
            if ("员工履历".equals(dataSourceCaption)) {// 如果是基本信息
                SalaryDataObject so = (SalaryDataObject) this.getData(dataSourceCaption, parameter);
                if (jdfo.getType() == JsDataValue.TYPE_NORMAL) {
                    cell.setValue(so.getString(jdfo.getField()));
                } else if (jdfo.getType() == JsDataValue.TYPE_FORMULA) {
                    // TODO 公式处理
                    cell.setValue(so.getString(jdfo.getField()));
                } else if (jdfo.getType() == JsDataValue.TYPE_PHOTO) {
                    String value = so.getString(jdfo.getField());

                    ImageValue o = new ImageValue();
                    o.setData(SalaryHelper.INSTANCE.getPhotoData(value));
                    cell.setValue(o);
                }
            } else {
                @SuppressWarnings("unchecked")
                List<SalaryDataObject> lso = (List<SalaryDataObject>) this.getData(dataSourceCaption, parameter);
                if (jdfo.getType() == JsDataValue.TYPE_NORMAL) {
                    int row = cell.getRow();
                    int column = cell.getColumn();
                    int ii = 0;
                    //把对象内容清空，避免没数据的时候不能正确显示
                    cell.setValue("");
                    for (SalaryDataObject sdo : lso) {
                        model.setCellValue(column, row + ii, sdo.getString(jdfo.getField()));

                        ii++;
                        if (row + ii + 1 == model.getRowCount()) {
                            break;
                        }
                    }
                } else if (jdfo.getType() == JsDataValue.TYPE_FORMULA) {
                    String formula = jdfo.getFormula();
                    Matcher macher = REG_FIELD.matcher(formula);
                    List<String> fields = new ArrayList<String>();
                    while (macher.find()) {
                        fields.add(macher.group(1));
                    }

                    StringBuilder sb = new StringBuilder();
                    for (SalaryDataObject sdo : lso) {
                        String itemStr = formula;
                        for (String field : fields) {
                            itemStr = itemStr.replaceAll("\\{" + field + "\\}", sdo.getString(field));
                        }
                        sb.append(itemStr);
                        sb.append("\n");
                    }

                    if (sb.length() > 1) {
                        sb.deleteCharAt(sb.length() - 1);
                    }
                    cell.setValue(sb.toString());
                }
            }
        }

        return calcModel;
    }
}
